package com.example.mytestdemo.extensions

import android.view.View
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

const val VIEW_SCOPE_TAG = -11186

val View.viewScope: CoroutineScope
    get() {
        var scope: CoroutineScope? = getTag(VIEW_SCOPE_TAG) as? CoroutineScope
        if (scope == null) {
            scope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
            setTag(VIEW_SCOPE_TAG, scope)
        }
        addOnAttachStateChangeListener(object : SimpleOnAttachStateChangeListener() {
            override fun onViewDetachedFromWindow(v: View) {
                runCatching {
                    scope.cancel()
                }
                removeOnAttachStateChangeListener(this)
            }
        })
        return scope
    }

fun <T> CancellableContinuation<T>.safeResume(value: T) {
    if (isActive) {
        this.resume(value)
    }
}

fun <T> CancellableContinuation<T>.safeResumeWithException(exception: Throwable) {
    if (isActive) {
        this.resumeWithException(exception)
    }
}

fun <T> Flow<T>.timeOut(timeMillis: Long): Flow<T> {
    return flow {
        withTimeout(timeMillis) {
            collect { value ->
                return@collect emit(value)
            }
        }
    }
}